namespace practiceCourse4 {
	class ListNode {
		val: number;
		next: ListNode | null;
		constructor(val?: number, next?: ListNode | null) {
			this.val = val === undefined ? 0 : val;
			this.next = next === undefined ? null : next;
		}
	}
	class MyLinkedList {
		length: number;
		dummyNode: ListNode;
		constructor() {
			this.length = 0;
			this.dummyNode = new ListNode();
		}

		// 获取指定位置的节点
		getNode(index: number): ListNode {
			let cur: ListNode = this.dummyNode;
			while (index >= 0 && cur.next) {
				cur = cur.next;
				index--;
			}
			return cur;
		}

		get(index: number): number {
			if (index > -1 && index < this.length) {
				return this.getNode(index).val;
			} else {
				return -1;
			}
		}

		addAtHead(val: number): void {
			let newNode = new ListNode(val, this.dummyNode.next);
			this.dummyNode.next = newNode;
			this.length++;
		}

		addAtTail(val: number): void {
			let tailNode = this.getNode(this.length - 1);
			tailNode.next = new ListNode(val);
			this.length++;
		}

		addAtIndex(index: number, val: number): void {
			if (index > this.length) return;
			if (index === this.length) {
				this.addAtTail(val);
				return;
			}
      if (index === 0) {
        this.addAtHead(val)
        return
      } else {
        let preNode = this.getNode(index - 1)
        let curNode = new ListNode(val)
        curNode.next = preNode.next
        preNode.next = curNode
        this.length++
      }
		}

		deleteAtIndex(index: number): void {
      if (index >= 0 && index < this.length) {
        if (index === 0 && this.dummyNode.next) {
          this.dummyNode.next = this.dummyNode.next.next
          this.length--
        } else {
          let preNode = this.getNode(index - 1)
          preNode.next = preNode.next?.next as ListNode
          this.length--
        }
      }
    }
	}

	/**
	 * Your MyLinkedList object will be instantiated and called as such:
	 * var obj = new MyLinkedList()
	 * var param_1 = obj.get(index)
	 * obj.addAtHead(val)
	 * obj.addAtTail(val)
	 * obj.addAtIndex(index,val)
	 * obj.deleteAtIndex(index)
	 */
}
